package xyz.hubery.handler;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.jwt.Jwt;
import org.springframework.security.jwt.JwtHelper;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.tio.core.ChannelContext;
import org.tio.core.Tio;
import org.tio.http.common.HttpRequest;
import org.tio.http.common.HttpResponse;
import org.tio.websocket.common.WsRequest;
import org.tio.websocket.server.handler.IWsMsgHandler;
import xyz.hubery.vo.ResponseEntity;

import java.util.Objects;

/**
 * Ws 消息处理器
 */
@Component
@Slf4j
public class WebSocketMessageHandler implements IWsMsgHandler {

    /**
     * 握手时执行
     */
    @Override
    public HttpResponse handshake(HttpRequest httpRequest, HttpResponse httpResponse, ChannelContext channelContext) throws Exception {
        String clientIp = httpRequest.getClientIp();
        log.info("收到来自 {} 的握手包",clientIp);
        return httpResponse;
    }

    /**
     * 握手成功后执行
     */
    @Override
    public void onAfterHandshaked(HttpRequest httpRequest, HttpResponse httpResponse, ChannelContext channelContext) throws Exception {
    }

    /**
     * 接收到字节消息执行
     */
    @Override
    public Object onBytes(WsRequest wsRequest, byte[] bytes, ChannelContext channelContext) throws Exception {
        log.info("接收到的消息长度为: {}",bytes.length);
        return null;
    }

    /**
     * 当客户端发 close flag 时，会走这个方法
     */
    @Override
    public Object onClose(WsRequest wsRequest, byte[] bytes, ChannelContext channelContext) throws Exception {
        log.info("客户端发起关闭连接请求");
        Tio.remove(channelContext,"关闭");
        return null;
    }

    /**
     * 接收到文本信息处理
     */
    @Override
    public Object onText(WsRequest wsRequest, String text, ChannelContext channelContext) throws Exception {

        log.info("接收到数据：{}",text);

        if(Objects.equals("ping",text)) {
            return "pong";
        }

        JSONObject payload = JSONObject.parseObject(text);
        String sub = payload.getString("sub");
        String req = payload.getString("req");
        String cancel = payload.getString("cancel");
        String id = payload.getString("id");

        // 如果用户已登录，绑定用户
        String authorization = payload.getString("authorization");
        if(StringUtils.hasText(authorization) && authorization.startsWith("bearer ")) {
            // 解析用户id
            String token = authorization.replace("bearer ", "");
            Jwt jwt = JwtHelper.decode(token);
            String jwtClaims = jwt.getClaims();
            JSONObject jsonObject = JSONObject.parseObject(jwtClaims);
            String userId = jsonObject.getString("user_name");
            Tio.bindUser(channelContext,userId);  // 绑定用户
        }
        if(StringUtils.hasText(sub)) {
            // 绑定群组
            Tio.bindGroup(channelContext,sub);
            //返回值是要发送给客户端的内容，一般都是返回 null
            return new ResponseEntity()
                    .setId(id)
                    .setSubbed(sub)
                    .setStatus("ok")
                    .build();
        }else if(StringUtils.hasText(req)) {

        }else if(StringUtils.hasText(cancel)) {
            // 取消订阅
            Tio.unbindGroup(cancel, channelContext);
            return new ResponseEntity()
                    .setId(id)
                    .setCanceled(cancel)
                    .setStatus("ok")
                    .build();
        }
        return null;
    }
}
